﻿/* Autoduel Game
 * CS4911 Senior Design Project
 * Fall 2010 Semester
 * Ian Axelrod, Liz Ha, Andrew Muldowney, Edward Futch
 */
using System;
using System.Collections.Generic;

using AutoduelClient.GameClient.Network;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using AutoduelClient.GameClient.Locations;
using AutoduelClient.GameClient.Player;

/// <summary>
/// Note: Point coords for each object starting location below (top-left corner of png file)
/// assembly: 4,4
/// fbi: 4,120
/// salvage: 180,4
/// pub: 196,125
/// weapon: 188,192
/// arena: 400,148
/// truck: 400,4
/// garage: 392,72
/// All images are 128x64, wxh
/// except arena and assembly: 128x128
/// </summary>
namespace AutoduelClient.GameClient.World
{
    /// <summary>
    /// Represents one of the grids that makes up an autoduel World
    /// </summary>
    public class Grid
    {
		#region Static Methods (1)
		/// <summary>
        /// Creates a grid object from the packet presented
        /// </summary>
        /// <param name="packet">the packet to decode</param>
        /// <returns>The grid object created from the packet</returns>
        public static Grid DecodePacket(byte[] packet)
        {
            int i = 1;
            Grid grid = new Grid();

            grid.Height = Util.ReverseInt32(BitConverter.ToInt32(packet, i));
            grid.Width = Util.ReverseInt32(BitConverter.ToInt32(packet, i + 4));
            i += 8;
            grid.Background = Util.MakeString(packet, ref i);
            grid.RealCoords = new Coordinate(Util.ReverseInt32(BitConverter.ToInt32(packet, i)), 
                Util.ReverseInt32(BitConverter.ToInt32(packet, i + 4)));
            grid.Index = new Coordinate(Util.ReverseInt32(BitConverter.ToInt32(packet, i + 8)),
                Util.ReverseInt32(BitConverter.ToInt32(packet, i + 12)));
            grid.IsPlayerGrid = packet[i + 16];

            return grid;
        }
		#endregion

        /// <summary>
        /// Height of the grid (determined by server)
        /// </summary>
        public static int GRID_HEIGHT = 288;

        /// <summary>
        /// Width of the grid (determined by server)
        /// </summary>
        public static int GRID_WIDTH = 512;

		#region Fields (7)
		// used to bound actual image to grid for background
        private Texture2D bgResource;

		// the coordinates of this grid on the server world
        private Coordinate realCoords;

        // index of this grid in the world's grids
        private Coordinate index;

        /// <summary>
        /// Get/Set the index of this grid
        /// </summary>
        public Coordinate Index
        {
            get { return index; }
            set { index = value; }
        }

		// mark that this grid is this session's central grid
        private byte isPlayerGrid;

		// players present in this grid
        private Dictionary<string, Player.Player> players = new Dictionary<string, Player.Player>();

		// how tall is a grid
        private int height;
		// how wide is a grid
        private int width;

		// a link to the background image for this grid
        private string background;

        // locations present on this grid
        private Dictionary<Coordinate, Location> locations = new Dictionary<Coordinate, Location>();

        /// <summary>
        /// Get/Set locations present on this grid
        /// </summary>
        public Dictionary<Coordinate, Location> Locations
        {
            get { return locations; }
            set { locations = value; }
        }
		#endregion

		#region Properties (6)
		/// <summary>
        /// Gets/Sets the link to the background image for this grid
        /// </summary>
        public string Background
        {
            get { return background; }
            set { background = value; }
        }
		/// <summary>
        /// Gets/Sets the background texture used for this grid
        /// </summary>
        public Texture2D BgResource
        {
            get { return bgResource; }
            set { bgResource = value; }
        }
		/// <summary>
        /// Gets/Sets how tall a grid is
        /// </summary>
        public int Height
        {
            get { return height; }
            set { height = value; }
        }
		/// <summary>
        /// Gets/Sets that this grid is this session's centralgrid
        /// </summary>
        public byte IsPlayerGrid
        {
            get { return isPlayerGrid; }
            set { isPlayerGrid = value; }
        }
		/// <summary>
        /// Gets/Sets the real (server) coordinates of this grid
        /// </summary>
        public Coordinate RealCoords
        {
            get { return realCoords; }
            set { realCoords = value; }
        }
		/// <summary>
        /// Gets/Sets how wide a grid is
        /// </summary>
        public int Width
        {
            get { return width; }
            set { width = value; }
        }
		#endregion

		#region Methods (3)

		/// <summary>
        /// Adds a player to this grid
        /// </summary>
        /// <param name="player">The player to add</param>
        public void AddPlayer(Player.Player player)
        {
            System.Diagnostics.Debug.WriteLine("Added player: " + player.ToString() + " to grid: " + this.ToString());
            this.players.Add(player.Name, player);
        }

		/// <summary>
        /// Removes a player from this grid
        /// </summary>
        /// <param name="player">The player to remove</param>
        /// <returns>True if the player was removed</returns>
        public bool RemovePlayer(Player.Player player)
        {
            System.Diagnostics.Debug.WriteLine("Removed player: " + player.ToString() + " from grid: " + this.ToString());
            return this.players.Remove(player.Name);
        }

        /// <summary>
        /// Checks to see if the coordinate passed in is near any
        /// location of the grid
        /// </summary>
        /// <param name="coord">The coordinate to check around</param>
        /// <returns>The location we are near, or null otherwise</returns>
        public Location NearLocation(Coordinate coord)
        {
            foreach (Location location in locations.Values)
            {
                if (Math.Abs(location.Entrance.X - coord.X) <= 10 && Math.Abs(location.Entrance.Y - coord.Y) <= 10)
                {
                    return location;
                }
            }
            return null;
        }

		/// <summary>
        /// Converts this grid object to its string representation
        /// </summary>
        /// <returns>The string representation of this grid</returns>
        public override string ToString()
        {
            return "Background: " + this.background + " -- Real Coordinates: " + this.realCoords + " -- index: " + this.index;
        }

		#endregion
    }
}
